package org.gmapschallenge;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Random;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;

@SuppressWarnings("serial")
public class GmcServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		StringBuffer kml = new StringBuffer(
				"<?xml version=\"1.0\" encoding=\"UTF-8\"?><kml xmlns=\"http://www.opengis.net/kml/2.2\"><Document><name>Google Maps Challenge</name><open>1</open>");
		// generate styles
		for (int i = 1; i < 9; i++) {
			kml.append("<Style id=\"s" + i + "\"><IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/paddle/"
					+ i + ".png</href></Icon></IconStyle></Style>");
		}
		DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
		Query query = new Query("Code");
		PreparedQuery pq = datastore.prepare(query);
		List<Entity> codes = pq.asList(FetchOptions.Builder.withLimit(200));
		for (Entity code : codes) {
			String points = (String) code.getProperty("points");
			String lat = (String) code.getProperty("lat");
			String lon = (String) code.getProperty("lon");
			long number = (Long) code.getProperty("number");
			kml.append("<Placemark><name>#" + number + ": " + points + " b.</name><styleUrl>#s" + points
					+ "</styleUrl><Point><coordinates>" + lon + "," + lat + ",0</coordinates></Point></Placemark>");
		}
		kml.append("</Document></kml>");

		resp.setContentType("application/vnd.google-earth.kml+xml");
		resp.getWriter().println(kml.toString());
	}

	/**
	 * Formats @gmail addresses without gmail, display other Google Apps plainly
	 */
	public static String formatMail(String mail) {
		if (mail.endsWith("@gmail.com")) {
			return mail.substring(0, mail.length() - 10);
		} else {
			return mail;
		}
	}

	/**
	 * Generates random code for QR codes
	 */
	public static String randomCode() {
		String sha = SHA1(String.valueOf(new Random().nextLong()));
		return sha.substring(0, 10);
	}

	private static String SHA1(String text) {
		MessageDigest md;
		try {
			md = MessageDigest.getInstance("SHA-1");

			byte[] sha1hash = new byte[40];
			md.update(text.getBytes("utf-8"), 0, text.length());

			sha1hash = md.digest();
			return convertToHex(sha1hash);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return null;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
	}

	private static String convertToHex(byte[] data) {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < data.length; i++) {
			int halfbyte = (data[i] >>> 4) & 0x0F;
			int two_halfs = 0;
			do {
				if ((0 <= halfbyte) && (halfbyte <= 9))
					buf.append((char) ('0' + halfbyte));
				else
					buf.append((char) ('a' + (halfbyte - 10)));
				halfbyte = data[i] & 0x0F;
			} while (two_halfs++ < 1);
		}
		return buf.toString();
	}
}
